﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using RATSharp.Model;
using RATSharp.Collection;
using RATSharp.Rest;
using System.Threading.Tasks;


namespace RATSharp.Cal
{
    /// <summary>
    /// Abstract dat aprovider for Calendar instance. All implementors shall provide
    /// data for calendar structure.
    /// </summary>
    public abstract class AbstractCalendarDataProvider
    {
        /// <summary>
        /// Data for calendar.
        /// </summary>
        public MultiDictionary<int, Period> data { get; private set; }
        private Reservations reservationsContext;

        /// <summary>
        /// REST service used for communication.
        /// </summary>
        protected RestService service { get; set; }
        /// <summary>
        /// which month is evaluated.
        /// </summary>
        protected int month { get; set; }
        /// <summary>
        /// which year is evaluated.
        /// </summary>
        protected int year { get; set; }

        /// <summary>
        /// Returns a REST task which should fill calendar data structure.
        /// </summary>
        /// <param name="firstDayInMonth">since</param>
        /// <param name="LastDayInMonth">to</param>
        /// <returns>REST task</returns>
        protected abstract Task<Reservations> getTask(DateTime firstDayInMonth, DateTime LastDayInMonth);

        /// <summary>
        /// Reloads calendar data model.
        /// </summary>
        public void invalidate()
        {
            DateTime date = new DateTime(year, month, 1);
            DateTime firstDayInMonth;
            DateTime LastDayInMonth;
            MenuUtilities.FirstAndLastDayOfMonth(date, out firstDayInMonth, out LastDayInMonth);

            Reservations responseRes;
            if (!MenuUtilities.WaitForCommTask(getTask(firstDayInMonth, LastDayInMonth), out responseRes))
            {
                return;
            }

            reservationsContext = responseRes;

            MenuUtilities.MakeBidirectionalConnection(reservationsContext);

            //start to parse data into suitable collection
            data = sortPeriodsPeerDay(year, month);


        }


        private MultiDictionary<int, Period> sortPeriodsPeerDay(int year, int month)
        {
            int daysInMonth = System.DateTime.DaysInMonth(year, month);
            MultiDictionary<int, Period> mdict = new MultiDictionary<int, Period>();
            DateTime dateTimeDayBegin = new DateTime(year, month, 1);
            for (int i = 1; i <= daysInMonth; i++)
            {
                DateTime dateTimeDayEnd = dateTimeDayBegin.Date.AddDays(1);
                foreach (Reservation res in reservationsContext)
                {
                    foreach (Period period in res.periods)
                    {

                        if ((DateTime.Compare(dateTimeDayBegin, period.fromDate) >= 0 && DateTime.Compare(dateTimeDayBegin, period.toDate) <= 0) ||
                        (DateTime.Compare(dateTimeDayBegin, period.fromDate) <= 0 && DateTime.Compare(dateTimeDayEnd, period.fromDate) >= 0))
                        {
                            mdict.Add(i, period);
                        }
                    }
                }
                dateTimeDayBegin = dateTimeDayEnd;
            }
            return mdict;
        }

    }
}
